Backbone.View.extend.moveToNextCell   D
last analyzed

Complexity

Conditions 21
Paths 13

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 21
c 2
b 0
f 0
nc 13
nop 3
dl 0
loc 48
rs 4.884

How to fix   Complexity   

Complexity

Complex classes like Backbone.View.extend.moveToNextCell often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import Backbone from 'backbone';
0 ignored issues
show
introduced by
Definition for rule 'keyword-spacing' was not found
Loading history...
2
import _ from 'underscore';
3
import {
4
  Backgrid
5
} from './core.js';
6
import {
7
  Columns
8
} from './columns.js';
9
import {
10
  Row
11
} from './row.js';
12
import {
13
  EmptyRow
14
} from './empty_row.js';
15
16
/*
17
  backgrid
18
  http://github.com/wyuenho/backgrid
19
20
  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
21
  Licensed under the MIT license.
22
*/
23
24
/**
25
   Body is the table body which contains the rows inside a table. Body is
26
   responsible for refreshing the rows after sorting, insertion and removal.
27
28
   @class Backgrid.Body
29
   @extends Backbone.View
30
*/
31
var Body = Backgrid.Body = Backbone.View.extend({
32
33
  /** @property */
34
  tagName: "tbody",
35
36
  /**
37
     Initializer.
38
39
     @param {Object} options
40
     @param {Backbone.Collection} options.collection
41
     @param {Backbone.Collection.<Backgrid.Column>|Array.<Backgrid.Column>|Array.<Object>} options.columns
42
     Column metadata.
43
     @param {Backgrid.Row} [options.row=Backgrid.Row] The Row class to use.
44
     @param {string|function(): string} [options.emptyText] The text to display in the empty row.
45
46
     @throws {TypeError} If options.columns or options.collection is undefined.
47
48
     See Backgrid.Row.
49
  */
50
  initialize: function (options) {
51
52
    this.columns = options.columns;
53
    if (!(this.columns instanceof Backbone.Collection)) {
54
      this.columns = new Columns(this.columns);
55
    }
56
57
    this.row = options.row || this.row || Row;
58
    this.rows = this.collection.map(function (model) {
59
      var row = new this.row({
0 ignored issues
show
introduced by
A constructor name should not start with a lowercase letter.
Loading history...
60
        columns: this.columns,
61
        model: model
62
      });
63
64
      return row;
65
    }, this);
66
67
    this.emptyText = options.emptyText;
68
    this._unshiftEmptyRowMayBe();
69
70
    var collection = this.collection;
71
    this.listenTo(collection, "add", this.insertRow);
72
    this.listenTo(collection, "remove", this.removeRow);
73
    this.listenTo(collection, "sort", this.refresh);
74
    this.listenTo(collection, "reset", this.refresh);
75
    this.listenTo(collection, "backgrid:sort", this.sort);
76
    this.listenTo(collection, "backgrid:edited", this.moveToNextCell);
77
78
    this.listenTo(this.columns, "add remove", this.updateEmptyRow);
79
  },
80
81
  _unshiftEmptyRowMayBe: function () {
82
    if (this.rows.length === 0 && this.emptyText != null) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if this.rows.length === 0 && this.emptyText != null is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
introduced by
Use ‘===’ to compare with ‘null’.
Loading history...
Bug Best Practice introduced by
Apart from some edge-cases, it is generally advisable to use the strict comparison !== instead of !=.

The loose comparison such as == or != might produce some weird results for some values, unless you explicitly want to have this behavior here, better use the strict alternative.

Learn more about loose comparison in Javascript.

Loading history...
83
      this.emptyRow = new EmptyRow({
84
        emptyText: this.emptyText,
85
        columns: this.columns
86
      });
87
88
      this.rows.unshift(this.emptyRow);
89
      return true
90
    }
91
  },
92
93
  /**
94
     This method can be called either directly or as a callback to a
95
     [Backbone.Collecton#add](http://backbonejs.org/#Collection-add) event.
96
97
     When called directly, it accepts a model or an array of models and an
98
     option hash just like
99
     [Backbone.Collection#add](http://backbonejs.org/#Collection-add) and
100
     delegates to it. Once the model is added, a new row is inserted into the
101
     body and automatically rendered.
102
103
     When called as a callback of an `add` event, splices a new row into the
104
     body and renders it.
105
106
     @param {Backbone.Model} model The model to render as a row.
107
     @param {Backbone.Collection} collection When called directly, this
108
     parameter is actually the options to
109
     [Backbone.Collection#add](http://backbonejs.org/#Collection-add).
110
     @param {Object} options When called directly, this must be null.
111
112
     See:
113
114
     - [Backbone.Collection#add](http://backbonejs.org/#Collection-add)
115
  */
116
  insertRow: function (model, collection, options) {
117
118
    if (this.rows[0] instanceof EmptyRow) this.rows.pop().remove();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'if' condition.
Loading history...
119
120
    // insertRow() is called directly
121
    if (!(collection instanceof Backbone.Collection) && !options) {
122
      this.collection.add(model, (options = collection));
0 ignored issues
show
Unused Code introduced by
The assignment to variable options seems to be never used. Consider removing it.
Loading history...
123
      return;
124
    }
125
126
    var row = new this.row({
0 ignored issues
show
introduced by
A constructor name should not start with a lowercase letter.
Loading history...
127
      columns: this.columns,
128
      model: model
129
    });
130
131
    var index = collection.indexOf(model);
132
    this.rows.splice(index, 0, row);
133
134
    var $el = this.$el;
135
    var $children = $el.children();
136
    var $rowEl = row.render().$el;
137
138
    if (index >= $children.length) {
139
      $el.append($rowEl);
140
    } else {
141
      $children.eq(index).before($rowEl);
142
    }
143
144
    return this;
145
  },
146
147
  /**
148
     The method can be called either directly or as a callback to a
149
     [Backbone.Collection#remove](http://backbonejs.org/#Collection-remove)
150
     event.
151
152
     When called directly, it accepts a model or an array of models and an
153
     option hash just like
154
     [Backbone.Collection#remove](http://backbonejs.org/#Collection-remove) and
155
     delegates to it. Once the model is removed, a corresponding row is removed
156
     from the body.
157
158
     When called as a callback of a `remove` event, splices into the rows and
159
     removes the row responsible for rendering the model.
160
161
     @param {Backbone.Model} model The model to remove from the body.
162
     @param {Backbone.Collection} collection When called directly, this
163
     parameter is actually the options to
164
     [Backbone.Collection#remove](http://backbonejs.org/#Collection-remove).
165
     @param {Object} options When called directly, this must be null.
166
167
     See:
168
169
     - [Backbone.Collection#remove](http://backbonejs.org/#Collection-remove)
170
  */
171
  removeRow: function (model, collection, options) {
172
173
    // removeRow() is called directly
174
    if (!options) {
175
      this.collection.remove(model, (options = collection));
0 ignored issues
show
Unused Code introduced by
The assignment to variable options seems to be never used. Consider removing it.
Loading history...
176
      if (this._unshiftEmptyRowMayBe()) {
177
        this.render();
178
      }
179
      return;
180
    }
181
182
    if (_.isUndefined(options.render) || options.render) {
183
      this.rows[options.index].remove();
184
    }
185
186
    this.rows.splice(options.index, 1);
187
    if (this._unshiftEmptyRowMayBe()) {
188
      this.render();
189
    }
190
191
    return this;
192
  },
193
194
  /**
195
     Rerender the EmptyRow which empties the DOM element, creates the td with the
196
     updated colspan, and appends it back into the DOM
197
  */
198
199
  updateEmptyRow: function () {
200
    if (this.emptyRow != null) {
0 ignored issues
show
introduced by
Use ‘===’ to compare with ‘null’.
Loading history...
Bug Best Practice introduced by
Apart from some edge-cases, it is generally advisable to use the strict comparison !== instead of !=.

The loose comparison such as == or != might produce some weird results for some values, unless you explicitly want to have this behavior here, better use the strict alternative.

Learn more about loose comparison in Javascript.

Loading history...
201
      this.emptyRow.render();
202
    }
203
  },
204
205
  /**
206
     Reinitialize all the rows inside the body and re-render them. Triggers a
207
     Backbone `backgrid:refresh` event from the collection along with the body
208
     instance as its sole parameter when done.
209
  */
210
  refresh: function () {
211
    for (var i = 0; i < this.rows.length; i++) {
212
      this.rows[i].remove();
213
    }
214
215
    this.rows = this.collection.map(function (model) {
216
      var row = new this.row({
0 ignored issues
show
introduced by
A constructor name should not start with a lowercase letter.
Loading history...
217
        columns: this.columns,
218
        model: model
219
      });
220
221
      return row;
222
    }, this);
223
    this._unshiftEmptyRowMayBe();
224
225
    this.render();
226
227
    this.collection.trigger("backgrid:refresh", this);
228
229
    return this;
230
  },
231
232
  /**
233
     Renders all the rows inside this body. If the collection is empty and
234
     `options.emptyText` is defined and not null in the constructor, an empty
235
     row is rendered, otherwise no row is rendered.
236
  */
237
  render: function () {
238
    this.$el.empty();
239
240
    var fragment = document.createDocumentFragment();
241
    for (var i = 0; i < this.rows.length; i++) {
242
      var row = this.rows[i];
243
      fragment.appendChild(row.render().el);
244
    }
245
246
    this.el.appendChild(fragment);
247
248
    this.delegateEvents();
249
250
    return this;
251
  },
252
253
  /**
254
     Clean up this body and it's rows.
255
256
     @chainable
257
  */
258
  remove: function () {
259
    for (var i = 0; i < this.rows.length; i++) {
260
      var row = this.rows[i];
261
      row.remove.apply(row, arguments);
262
    }
263
    return Backbone.View.prototype.remove.apply(this, arguments);
264
  },
265
266
  /**
267
     If the underlying collection is a Backbone.PageableCollection in
268
     server-mode or infinite-mode, a page of models is fetched after sorting is
269
     done on the server.
270
271
     If the underlying collection is a Backbone.PageableCollection in
272
     client-mode, or any
273
     [Backbone.Collection](http://backbonejs.org/#Collection) instance, sorting
274
     is done on the client side. If the collection is an instance of a
275
     Backbone.PageableCollection, sorting will be done globally on all the pages
276
     and the current page will then be returned.
277
278
     Triggers a Backbone `backgrid:sorted` event from the collection when done
279
     with the column, direction and a reference to the collection.
280
281
     @param {Backgrid.Column|string} column
282
     @param {null|"ascending"|"descending"} direction
283
284
     See [Backbone.Collection#comparator](http://backbonejs.org/#Collection-comparator)
285
  */
286
  sort: function (column, direction) {
287
288
    if (!_.contains(["ascending", "descending", null], direction)) {
289
      throw new RangeError('direction must be one of "ascending", "descending" or `null`');
290
    }
291
292
    if (_.isString(column)) column = this.columns.findWhere({
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'if' condition.
Loading history...
293
      name: column
294
    });
295
296
    var collection = this.collection;
297
298
    var order;
299
    if (direction === "ascending") order = -1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'if' condition.
Loading history...
300
    else if (direction === "descending") order = 1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'if' condition.
Loading history...
301
    else order = null;
0 ignored issues
show
introduced by
Expected { after 'else'.
Loading history...
302
303
    var comparator = this.makeComparator(column.get("name"), order,
304
      order ?
305
      column.sortValue() :
306
      function (model) {
307
        return model.cid.replace('c', '') * 1;
308
      });
309
310
    if (Backbone.PageableCollection &&
311
      collection instanceof Backbone.PageableCollection) {
312
313
      collection.setSorting(order && column.get("name"), order, {
314
        sortValue: column.sortValue()
315
      });
316
317
      if (collection.fullCollection) {
318
        // If order is null, pageable will remove the comparator on both sides,
319
        // in this case the default insertion order comparator needs to be
320
        // attached to get back to the order before sorting.
321
        if (collection.fullCollection.comparator == null) {
0 ignored issues
show
introduced by
Use ‘===’ to compare with ‘null’.
Loading history...
Bug Best Practice introduced by
Apart from some edge-cases, it is generally advisable to use the strict comparison === instead of ==.

The loose comparison such as == or != might produce some weird results for some values, unless you explicitly want to have this behavior here, better use the strict alternative.

Learn more about loose comparison in Javascript.

Loading history...
322
          collection.fullCollection.comparator = comparator;
323
        }
324
        collection.fullCollection.sort();
325
        collection.trigger("backgrid:sorted", column, direction, collection);
326
        column.set("direction", direction);
327
      } else collection.fetch({
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'else'.
Loading history...
328
        reset: true,
329
        success: function () {
330
          collection.trigger("backgrid:sorted", column, direction, collection);
331
          column.set("direction", direction);
332
        }
333
      });
334
    } else {
335
      collection.comparator = comparator;
336
      collection.sort();
337
      collection.trigger("backgrid:sorted", column, direction, collection);
338
      column.set("direction", direction);
339
    }
340
341
    return this;
342
  },
343
344
  makeComparator: function (attr, order, func) {
345
346
    return function (left, right) {
347
      // extract the values from the models
348
      var l = func(left, attr),
349
        r = func(right, attr),
350
        t;
351
352
      // if descending order, swap left and right
353
      if (order === 1) t = l, l = r, r = t;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
introduced by
Expected { after 'if' condition.
Loading history...
introduced by
Expected an assignment or function call and instead saw an expression.
Loading history...
introduced by
Unexpected use of comma operator.
Loading history...
354
355
      // compare as usual
356
      if (l === r) return 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'if' condition.
Loading history...
357
      else if (l < r) return -1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'if' condition.
Loading history...
358
      return 1;
359
    };
360
  },
361
362
  /**
363
     Moves focus to the next renderable and editable cell and return the
364
     currently editing cell to display mode.
365
366
     Triggers a `backgrid:next` event on the model with the indices of the row
367
     and column the user *intended* to move to, and whether the intended move
368
     was going to go out of bounds. Note that *out of bound* always means an
369
     attempt to go past the end of the last row.
370
371
     @param {Backbone.Model} model The originating model
372
     @param {Backgrid.Column} column The originating model column
373
     @param {Backgrid.Command} command The Command object constructed from a DOM
374
     event
375
  */
376
  moveToNextCell: function (model, column, command) {
377
    var i = this.collection.indexOf(model);
378
    var j = this.columns.indexOf(column);
379
    var cell, renderable, editable, m, n;
380
381
    // return if model being edited in a different grid
382
    if (j === -1) return this;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'if' condition.
Loading history...
383
384
    this.rows[i].cells[j].exitEditMode();
385
386
    if (command.moveUp() || command.moveDown() || command.moveLeft() ||
387
      command.moveRight() || command.save()) {
388
      var l = this.columns.length;
389
      var maxOffset = l * this.collection.length;
390
391
      if (command.moveUp() || command.moveDown()) {
392
        m = i + (command.moveUp() ? -1 : 1);
393
        var row = this.rows[m];
394
        if (row) {
395
          cell = row.cells[j];
396
          if (Backgrid.callByNeed(cell.column.editable(), cell.column, model)) {
0 ignored issues
show
introduced by
Blocks are nested too deeply (4).
Loading history...
397
            cell.enterEditMode();
398
            model.trigger("backgrid:next", m, j, false);
399
          }
400
        } else model.trigger("backgrid:next", m, j, true);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
introduced by
Expected { after 'else'.
Loading history...
401
      } else if (command.moveLeft() || command.moveRight()) {
402
        var right = command.moveRight();
403
        for (var offset = i * l + j + (right ? 1 : -1); offset >= 0 && offset < maxOffset; right ? offset++ : offset--) {
404
          m = ~~(offset / l);
0 ignored issues
show
introduced by
Unexpected use of '~'.
Loading history...
405
          n = offset - m * l;
406
          cell = this.rows[m].cells[n];
407
          renderable = Backgrid.callByNeed(cell.column.renderable(), cell.column, cell.model);
408
          editable = Backgrid.callByNeed(cell.column.editable(), cell.column, model);
409
          if (renderable && editable) {
0 ignored issues
show
introduced by
Blocks are nested too deeply (4).
Loading history...
410
            cell.enterEditMode();
411
            model.trigger("backgrid:next", m, n, false);
412
            break;
413
          }
414
        }
415
416
        if (offset == maxOffset) {
0 ignored issues
show
Bug Best Practice introduced by
Apart from some edge-cases, it is generally advisable to use the strict comparison === instead of ==.

The loose comparison such as == or != might produce some weird results for some values, unless you explicitly want to have this behavior here, better use the strict alternative.

Learn more about loose comparison in Javascript.

Loading history...
417
          model.trigger("backgrid:next", ~~(offset / l), offset - m * l, true);
0 ignored issues
show
Bug introduced by
The variable m seems to not be initialized for all possible execution paths.
Loading history...
introduced by
Unexpected use of '~'.
Loading history...
418
        }
419
      }
420
    }
421
422
    return this;
423
  }
424
});
425
426
export {
427
  Body
428
};
429